#ifndef _NE_PARTICLE_ParticleEmitter_H_
#define _NE_PARTICLE_ParticleEmitter_H_

#include <mathematics/Random.h>
#include <partical/Particle.h>

namespace ne
{
    class NEAPI ParticleEmitter : public Particle
    {
        public:
            explicit ParticleEmitter(const std::string &type);

            ParticleEmitter(const ParticleEmitter &emitter);

            virtual const std::string& getEmitterType() const;

            virtual void setEmittedEmitterType(const std::string &type);
            virtual const std::string& getEmittedEmitterType() const;

            virtual void setEmissionRate(const real rate);
            virtual real getEmissionRate() const;

            virtual void setStartTime(const real v);
            virtual real getStartTime() const;

            virtual void setDuration(const real v);
            virtual real getDuration() const;
            virtual void setDuration(const real minV, const real maxV);
            virtual void setMinDuration(const real v);
            virtual real getMinDuration() const;
            virtual void setMaxDuration(const real v);
            virtual real getMaxDuration() const;

            virtual void setRepeatDelay(const real v);
            virtual real getRepeatDelay() const;
            virtual void setRepeatDelay(const real minV, const real maxV);
            virtual void setMinRepeatDelay(const real v);
            virtual real getMinRepeatDelay() const;
            virtual void setMaxRepeatDelay(const real v);
            virtual real getMaxRepeatDelay() const;

            virtual void setMass(const real m);
            virtual real getMass() const;
            virtual void setMass(const real minM, const real maxM);
            virtual void setMinMass(const real m);
            virtual real getMinMass() const;
            virtual void setMaxMass(const real m);
            virtual real getMaxMass() const;

            virtual void setAngle(const real v);
            virtual real getAngle() const;
            virtual void setAngle(const real minV, const real maxV);
            virtual void setMinAngle(const real v);
            virtual real getMinAngle() const;
            virtual void setMaxAngle(const real v);
            virtual real getMaxAngle() const;

            virtual void setVelocity(const real v);
            virtual real getVelocity() const;
            virtual void setVelocity(const real minV, const real maxV);
            virtual void setMinVelocity(const real v);
            virtual real getMinVelocity() const;
            virtual void setMaxVelocity(const real v);
            virtual real getMaxVelocity() const;

            virtual void setRotation(const real v);
            virtual real getRotation() const;
            virtual void setRotation(const real minV, const real maxV);
            virtual void setMinRotation(const real v);
            virtual real getMinRotation() const;
            virtual void setMaxRotation(const real v);
            virtual real getMaxRotation() const;

            virtual void setZoom(const real v);
            virtual real getZoom() const;
            virtual void setZoom(const real minV, const real maxV);
            virtual void setMinZoom(const real v);
            virtual real getMinZoom() const;
            virtual void setMaxZoom(const real v);
            virtual real getMaxZoom() const;

            virtual void setColorRange(const Color &c);
            virtual const Color& getColorRange() const;
            virtual void setColorRange(const Color &sC, const Color &eC);
            virtual void setStartColorRange(const Color &c);
            virtual const Color& getStartColorRange() const;
            virtual void setEndColorRange(const Color &c);
            virtual const Color& getEndColorRange() const;

            virtual void setLifetime(const real v);
            virtual real getLifetime() const;
            virtual void setLifetime(const real minV, const real maxV);
            virtual void setMinLifetime(const real v);
            virtual real getMinLifetime() const;
            virtual void setMaxLifetime(const real v);
            virtual real getMaxLifetime() const;

            virtual void setEnable(const bool b);
            virtual void enable();
            virtual void disable();
            virtual bool isEnable() const;

            virtual bool isParticleEmitter() const;

            virtual void setEmitting(const bool b);
            virtual bool isEmitting() const;

            virtual void initialParticle(Particle *pParticle);

            virtual void reset();

            virtual size_t genEmissionParticleCount(const real interval);
            virtual void genEmissionMass(real &m);
            virtual void genEmissionPosition(Vector3 &v);
            virtual void genEmissionOrientation(Quaternion &q);
            virtual void genEmissionScale(Vector3 &s);
            virtual void genEmissionColor(Color &c);
            virtual void genEmissionTexCoord(Vector2 &t);

            virtual void genEmissionVelocity(Vector3 &d, Vector3 &v);
            virtual void genEmissionRotation(Vector3 &a, real &r);
            virtual void genEmissionZoom(real &z);

            virtual void genEmissionLifetime(real &l);

            virtual ~ParticleEmitter();

        protected:
            virtual void _updateDurationAndRepeatDelay();

        private:
            ParticleEmitter();

            ParticleEmitter& operator = (const ParticleEmitter &);

        protected:
            const std::string mEmitterType;
            std::string mEmittedEmitterType;
            real mEmissionRate; // n/sec

            // The value for emitter run time
            real mStartTime;
            real mRemainStartTime; // It is for internal use
            real mMinDuration;
            real mMaxDuration;
            real mRemainDuration; // 0.0f = forever
            real mMinRepeatDelay;
            real mMaxRepeatDelay;
            real mRemainRepeatDelay;
            real mRemainInterval; // It is for internal use

            // The value for particles to initialize
            real mMinMass;
            real mMaxMass;

            real mMinAngle;
            real mMaxAngle;

            real mMinVelocity;
            real mMaxVelocity;

            real mMinRotation;
            real mMaxRotation;

            real mMinZoom;
            real mMaxZoom;

            Color mStartColorRange;
            Color mEndColorRange;

            real mMinLifetime;
            real mMaxLifetime;

            bool mEnable;
            bool mEmitting;
    };

    typedef std::vector<ParticleEmitter*> ParticleEmitterVector;
    typedef ParticleEmitterVector::iterator ParticleEmitterVectorIterator;
    typedef ParticleEmitterVector::const_iterator ParticleEmitterVectorConstIterator;

    typedef std::list<ParticleEmitter*> ParticleEmitterList;
    typedef ParticleEmitterList::iterator ParticleEmitterListIterator;
    typedef ParticleEmitterList::const_iterator ParticleEmitterListConstIterator;

    typedef std::map<std::string, ParticleEmitter*> ParticleEmitterMap;
    typedef ParticleEmitterMap::iterator ParticleEmitterMapIterator;
    typedef ParticleEmitterMap::const_iterator ParticleEmitterMapConstIterator;
};

#endif
